/**
 *====================================================
 * 文件名称: BulkstockInventoryServiceImpl.java
 * 修订记录：
 * No    日期				作者(操作:具体内容)
 * 1.    2015年09月23日	chenxy(创建:创建文件)
 *====================================================
 * 类描述：(说明未实现或其它不应生成javadoc的内容)
 */
package com.yuexunit.finance.project.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.yuexunit.finance.common.util.BeanUtils;
import com.yuexunit.finance.common.util.DateUtils;
import com.yuexunit.finance.project.entity.ContainerInventoryEntity;
import com.yuexunit.finance.project.entity.DeliveryNoticeEntity;
import com.yuexunit.finance.project.entity.FinanceBulkstockEntity;
import com.yuexunit.finance.project.entity.FinanceContractEntity;
import com.yuexunit.finance.project.entity.SupervisionConfirmationEntity;
import com.yuexunit.finance.project.entity.TallyingEntity;
import com.yuexunit.finance.project.entity.lexicon.AbnormalResultEnum;
import com.yuexunit.finance.project.entity.lexicon.AbnormalStateEnum;
import com.yuexunit.finance.project.entity.lexicon.AbnormalTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.BadassetsStateEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupModelEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.SupervisionStateEnum;
import com.yuexunit.finance.project.entity.lexicon.TallyingStateEnum;
import com.yuexunit.inject.annotation.Implements;
import com.yuexunit.page.PageCriteria;
import com.yuexunit.page.PageList;
import com.yuexunit.persist.PersistUtil;
import com.yuexunit.persist.annotation.Transactional;
import com.yuexunit.util.DateUtil;
import com.yuexunit.util.StringUtil;

/**
 * @ClassName: BulkstockInventoryServiceImpl
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author chenxy
 * @date 2015年09月23日 18:56:17
 */
@Implements(ContainerInventoryService.class)
public class ContainerInventoryServiceImpl implements ContainerInventoryService {

	private DetachedCriteria getEnabledDetachedCriteria() {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		return criteria;
	}

	@Override
	public Long createContainerInventory(ContainerInventoryEntity entity) {
		if (entity.getAbnormal() == null) {
			entity.setAbnormal(Boolean.TRUE);
		}
		if (entity.getAbnormalState() == null) {
			entity.setAbnormalState(AbnormalStateEnum.UNKNOWN);
		}
		entity.setAbnormalType(AbnormalTypeEnum.UNKNOWN);
		entity.setLatestAbnormalResult(AbnormalResultEnum.UNKNOWN);
		if (entity.getTallyingState() == null) {
			entity.setTallyingState(Boolean.FALSE);
		}
		if (StringUtils.isNotBlank(entity.getCaseNumber())) {
			entity.setCaseNumber(entity.getCaseNumber().toUpperCase());
		}
		if (entity.getAdjustment() == null) {
			entity.setAdjustment(BigDecimal.ZERO);
		}
		if (entity.getHarborState() == null) {
			entity.setHarborState(Boolean.FALSE);
		}

		if (entity.getSupervisionState() == null) {
			entity.setSupervisionState(SupervisionStateEnum.UNKNOWN);
		}
		if (entity.getSignState() == null) {
			entity.setSignState(Boolean.FALSE);
		}
		if (entity.getPickupModel() == null) {
			entity.setPickupModel(PickupModelEnum.UNKNOWN);
		}
		if (entity.getRedeemState() == null) {
			entity.setRedeemState(Boolean.FALSE);
		}
		if (entity.getBadassetsState() == null) {
			entity.setBadassetsState(BadassetsStateEnum.UNKNOWN);
		}
		if (entity.getDetainedState() == null) {
			entity.setDetainedState(Boolean.FALSE);
		}
		entity.setEnabled(Boolean.TRUE);
		entity.setCreateDateTime(DateUtil.now());
		entity.setUpdateDateTime(DateUtil.now());
		PersistUtil.insert(entity);
		return entity.getInventoryId();
	}

	@Override
	@Transactional
	public void updateContainerInventory(ContainerInventoryEntity entity) {
		ContainerInventoryEntity persist = inquireContainerInventory(entity.getInventoryId());
		BeanUtils.copyProperties(entity, persist);
		persist.setUpdateDateTime(DateUtil.now());
		if (StringUtils.isNotBlank(persist.getCaseNumber())) {
			persist.setCaseNumber(persist.getCaseNumber().toUpperCase());
		}
		if (StringUtils.isNotBlank(persist.getWaybillNumber())) {
			persist.setWaybillNumber(persist.getWaybillNumber().toUpperCase());
		}
		PersistUtil.update(persist);
	}

	@Override
	public void renovateContainerInventory(ContainerInventoryEntity persist) {
		if (StringUtils.isNoneBlank(persist.getCaseNumber())) {
			persist.setCaseNumber(persist.getCaseNumber().toUpperCase());
		}
		persist.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(persist);
	}

	@Override
	public void disableContainerInventory(Long inventoryId) {
		ContainerInventoryEntity persist = inquireContainerInventory(inventoryId);
		persist.setEnabled(Boolean.FALSE);
		persist.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(persist);
	}

	@Override
	@Transactional
	public void deleteContainerInventory(Long inventoryId) {
		PersistUtil.delete(ContainerInventoryEntity.class, inventoryId);
	}

	@Override
	public ContainerInventoryEntity inquireContainerInventory(Long inventoryId) {
		return PersistUtil.get(ContainerInventoryEntity.class, inventoryId);
	}

	@Override
	public ContainerInventoryEntity inquireTallyingContainerInventory(Long tallyingId, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("tallyingId", tallyingId));
		criteria.add(Restrictions.eq("caseNumber", caseNumber));
		List<ContainerInventoryEntity> list = PersistUtil.get(criteria);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public ContainerInventoryEntity inquireRecieveNoticeContainerInventory(Long recieveNoticeId, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("recieveNoticeId", recieveNoticeId));
		criteria.add(Restrictions.eq("caseNumber", caseNumber));
		List<ContainerInventoryEntity> list = PersistUtil.get(criteria);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	private List<ContainerInventoryEntity> inquireBulkstockInventoryList(Long tallyingId, Long transportNoticeId, Long deliveryId, Long[] inventoryIds, Long financeId, Date minPickupDate) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (tallyingId != null) {
			criteria.add(Restrictions.eq("tallyingId", tallyingId));
		}
		if (transportNoticeId != null) {
			criteria.add(Restrictions.eq("transportNoticeId", transportNoticeId));
		}
		if (deliveryId != null) {
			criteria.add(Restrictions.eq("deliveryId", deliveryId));
		}
		if (inventoryIds != null && inventoryIds.length > 0) {
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
		}
		if (financeId != null) {
			criteria.add(Restrictions.eq("financeId", financeId));
		}
		if (minPickupDate != null) {
			criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
			criteria.add(Restrictions.ge("pickupableDate", minPickupDate));
		}
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireTallyingContainerInventoryList(Long tallyingId) {
		return inquireBulkstockInventoryList(tallyingId, null, null, null, null, null);
	}

	@Override
	public List<ContainerInventoryEntity> inquireTransportContainerInventoryList(Long transportNoticeId) {
		return inquireBulkstockInventoryList(null, transportNoticeId, null, null, null, null);
	}

	@Override
	public List<ContainerInventoryEntity> inquireDeliveryNoticeContainerInventoryList(Long deliveryNoticeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("deliveryNoticeId", deliveryNoticeId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireDeliveryContainerInventoryList(Long deliveryId) {
		DetachedCriteria criteria = getEnabledDetachedCriteria();
		criteria.add(Restrictions.eq("deliveryId", deliveryId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireDeliveryContainerInventoryListByCondition(Long deliveryId, String caseNumber, String waybillNumber) {
		DetachedCriteria criteria = getEnabledDetachedCriteria();
		criteria.add(Restrictions.eq("deliveryId", deliveryId));
		if (StringUtil.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		if (StringUtil.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryList(Long logisticsCompanyInfoId) {
		DetachedCriteria criteria = getEnabledDetachedCriteria();
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.isNull("pickupId"));
		criteria.add(Restrictions.eq("logisticsCompanyInfoId", logisticsCompanyInfoId));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryList(Long[] inventoryIds) {
		if (inventoryIds == null || inventoryIds.length == 0) {
			return null;
		}
		return inquireBulkstockInventoryList(null, null, null, inventoryIds, null, null);
	}

	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryList(Long financeId, Date minValueDate) {
		return inquireBulkstockInventoryList(null, null, null, null, financeId, minValueDate);
	}

	@Override
	public List<ContainerInventoryEntity> inquireEffectiveContainerInventoryList(Long financeId) {
		SupervisionStateEnum[] supervisionState = new SupervisionStateEnum[] { SupervisionStateEnum.UNKNOWN, SupervisionStateEnum.ALREADY_REPORT, SupervisionStateEnum.ALREADY_SUPERVISE, SupervisionStateEnum.DELIVERY_SURE,
				SupervisionStateEnum.RELIEVE_SUPERVISE };
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.in("supervisionState", supervisionState));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireLoanNoticeContainerInventoryList(Long loanNoticeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("loanNoticeId", loanNoticeId));
		criteria.addOrder(Order.asc("valueDate"));
		return PersistUtil.get(criteria);
	}
	

	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryListByLocationId(String locationId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("locationId", locationId));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<Long> inquireLoanNoticeContainerInventoryIdList(Long loanNoticeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("loanNoticeId", loanNoticeId));
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("inventoryId")));
		return PersistUtil.get(criteria);
	}

	@Override
	public PageList<ContainerInventoryEntity> inquireContainerInventoryPageList(String enterpriseName, Long[] inventoryIds, Long financeId, String waybillNumber, Integer inventoryState, SupervisionStateEnum[] supervisionState, String caseNumber, Long loanNoticeId,
			PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.addOrder(Order.desc("tallyDateTime"));
		if (supervisionState != null && supervisionState.length > 0) {
			criteria.add(Restrictions.in("supervisionState", supervisionState));
		}
		if (financeId != null) {
			criteria.add(Restrictions.eq("financeId", financeId));
		}
		if (inventoryIds != null && inventoryIds.length > 0) {
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
		}
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		if (loanNoticeId != null) {
			criteria.add(Restrictions.eq("loanNoticeId", loanNoticeId));
		}
		if (StringUtil.isNotBlank(enterpriseName)) {
			criteria.add(Restrictions.like("enterpriseName", "%" + enterpriseName + "%"));
		}
		if (inventoryState != null) {
			if (PickupTypeEnum.AHEAD.ordinal() == inventoryState.intValue()) { // 提前还款-正常计息期前
				criteria.add(Restrictions.gt("pickupableDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (PickupTypeEnum.NORMAL.ordinal() == inventoryState.intValue()) { // 正常提货-正常计息期内(包括罚息)
				criteria.add(Restrictions.le("pickupableDate", DateUtils.formatBeginDay(new Date())));
//				criteria.add(Restrictions.ge("distrainDate", DateUtils.formatEndDay(new Date())));//TODO 暂时去除可提货日期验证
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (PickupTypeEnum.REDEEM.ordinal() == inventoryState.intValue()) { // 罚息后,被标注处置前
				criteria.add(Restrictions.lt("distrainDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.ge("handleDate", DateUtils.formatEndDay(new Date())));
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (4 == inventoryState.intValue()) { // 待处置
				criteria.add(Restrictions.lt("handleDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.isNull("pickupId"));
				criteria.add(Restrictions.eq("signState", Boolean.FALSE));
			}
		}
		criteria.addOrder(Order.desc("enterpriseId")).addOrder(Order.desc("financeId"));
		return PersistUtil.get(criteria, page);
	}
	
	@Override
	public PageList<ContainerInventoryEntity> inquireContainerInventoryPageLists(List<Long> financeIds,String enterpriseName, Long[] inventoryIds, Long financeId, String waybillNumber, Integer inventoryState, SupervisionStateEnum[] supervisionState, String caseNumber, Long loanNoticeId,
			String financeNumber,String bulkstockName, PageCriteria page) {
		List<Long> financeIds2 = null;
		if (bulkstockName !=null && !"".equals(bulkstockName)) {// 若有搜索货物名称
			DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
			if (StringUtils.isNotBlank(bulkstockName)) {
				criteria.add(Restrictions.like("bulkstockName", "%" + bulkstockName + "%"));
			}
			criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("financeId")));
			financeIds2 = PersistUtil.get(criteria);
			if (financeIds2.isEmpty()) {
				return new PageList<>(page);
			}
		}
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.addOrder(Order.desc("tallyDateTime"));
		if (supervisionState != null && supervisionState.length > 0) {
			criteria.add(Restrictions.in("supervisionState", supervisionState));
		}
		if (financeId != null) {
			criteria.add(Restrictions.eq("financeId", financeId));
		}
		if (financeIds2 != null && financeIds2.size() > 0) {
			criteria.add(Restrictions.in("financeId", financeIds2));
		}
		if (inventoryIds != null && inventoryIds.length > 0) {
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
		}
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		if (loanNoticeId != null) {
			criteria.add(Restrictions.eq("loanNoticeId", loanNoticeId));
		}
		if (StringUtil.isNotBlank(enterpriseName)) {
			criteria.add(Restrictions.like("enterpriseName", "%" + enterpriseName + "%"));
		}
		if (StringUtils.isNotBlank(financeNumber)) {
			criteria.add(Restrictions.like("financeNumber", "%" + financeNumber + "%"));
		}
		if (financeIds == null || financeIds.size() == 0) {
			return new PageList<ContainerInventoryEntity>(page);
		}
		criteria.add(Restrictions.in("financeId", financeIds));
		if (inventoryState != null) {
			if (PickupTypeEnum.AHEAD.ordinal() == inventoryState.intValue()) { // 提前还款-正常计息期前
				criteria.add(Restrictions.gt("pickupableDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (PickupTypeEnum.NORMAL.ordinal() == inventoryState.intValue()) { // 正常提货-正常计息期内(包括罚息)
				criteria.add(Restrictions.le("pickupableDate", DateUtils.formatBeginDay(new Date())));
//				criteria.add(Restrictions.ge("distrainDate", DateUtils.formatEndDay(new Date())));//TODO 暂时去除可提货日期验证
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (PickupTypeEnum.REDEEM.ordinal() == inventoryState.intValue()) { // 罚息后,被标注处置前
				criteria.add(Restrictions.lt("distrainDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.ge("handleDate", DateUtils.formatEndDay(new Date())));
				criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
				criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
				criteria.add(Restrictions.eq("abnormal", Boolean.TRUE)); // 无异常
				criteria.add(Restrictions.eq("detainedState", Boolean.FALSE)); // 未扣货
				criteria.add(Restrictions.eq("signState", Boolean.FALSE)); // 未签收
			}
			if (4 == inventoryState.intValue()) { // 待处置
				criteria.add(Restrictions.lt("handleDate", DateUtils.formatBeginDay(new Date())));
				criteria.add(Restrictions.isNull("pickupId"));
				criteria.add(Restrictions.eq("signState", Boolean.FALSE));
			}
		}
		criteria.addOrder(Order.desc("enterpriseId")).addOrder(Order.desc("financeId"));
		return PersistUtil.get(criteria, page);
	}
	
	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryList(List<Long> financeIds, Long enterpriseId,
			String financeNumber, String bulkstockName, String warehouseName) {
		List<Long> financeIds2 = null;
		if (StringUtil.isNotBlank(bulkstockName)) {// 若有搜索货物名称
			DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
			if (StringUtils.isNotBlank(bulkstockName)) {
				criteria.add(Restrictions.like("bulkstockName", "%" + bulkstockName + "%"));
			}
			criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("financeId")));
			financeIds2 = PersistUtil.get(criteria);
			if (financeIds2.isEmpty()) {
				return new ArrayList<ContainerInventoryEntity>();
			}
		}
		
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.addOrder(Order.desc("tallyDateTime"));
		
		if (financeIds2 != null && financeIds2.size() > 0) {
			criteria.add(Restrictions.in("financeId", financeIds2));
		}
		if (financeIds == null || financeIds.size() == 0) {
			return new ArrayList<ContainerInventoryEntity>();
		}
		criteria.add(Restrictions.in("financeId", financeIds));
		if (null != enterpriseId) {
			criteria.add(Restrictions.eq("enterpriseId", enterpriseId));
		}
		if (StringUtils.isNotBlank(financeNumber)) {
			criteria.add(Restrictions.like("financeNumber", "" + financeNumber + ""));
		}
		if (StringUtils.isNotBlank(warehouseName)) {
			criteria.add(Restrictions.eq("warehouseName", warehouseName));
		}
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<ContainerInventoryEntity> inquireInboundList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		
		criteria.add(Restrictions.isNotNull("locationId"));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireWaitTransportContainerInventoryList(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("tallyingState", Boolean.TRUE));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		criteria.add(Restrictions.isNull("transportNoticeId"));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireWaitDeliveryBulkstockInventoryList(DeliveryNoticeEntity deliveryNotice) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", deliveryNotice.getFinanceId()));
		criteria.add(Restrictions.eq("tallyingState", Boolean.TRUE));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		criteria.add(Restrictions.isNull("deliveryId"));
		if (StringUtils.isBlank(deliveryNotice.getSupervisionBatchNumber())) {
			criteria.add(Restrictions.eq("pickupId", deliveryNotice.getPickupId()));
		} else {
			String[] supervisionBatchNumbers = deliveryNotice.getSupervisionBatchNumber().split(",");
			DetachedCriteria dc = DetachedCriteria.forClass(SupervisionConfirmationEntity.class);
			dc.add(Restrictions.in("supervisionBatchNumber", supervisionBatchNumbers));
			dc.setProjection(Projections.projectionList().add(Projections.groupProperty("confirmationId")));
			List<Long> confirmationIds = PersistUtil.get(dc);
			if (confirmationIds.isEmpty()) {
				return new ArrayList<ContainerInventoryEntity>(0);
			}
			criteria.add(Restrictions.in("confirmationId", confirmationIds));
		}
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireUnSupervisionInventoryList(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.ne("supervisionState", SupervisionStateEnum.RELIEVE_SUPERVISE));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<ContainerInventoryEntity> inquireUnPickupInventoryList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.isNull("pickupId"));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireWaitLoanNoticeContainerInventoryList(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		criteria.addOrder(Order.asc("valueDate"));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public PageList<ContainerInventoryEntity> inquireWaitLoanNoticeContainerInventoryPageList(Long financeId, PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		criteria.addOrder(Order.asc("valueDate"));
		return PersistUtil.get(criteria, page);
	}

	@Override
	public PageList<ContainerInventoryEntity> inquireAbnormalContainerInventoryPageList(Long enterpriseId, PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("enterpriseId", enterpriseId));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		return PersistUtil.get(criteria, page);
	}

	@Override
	public List<ContainerInventoryEntity> inquirePickupContainerInventoryList(Long pickupId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("pickupId", pickupId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireSupervisionConfirmationContainerInventoryList(Long confirmationId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("confirmationId", confirmationId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireFacingSlipContainerInventoryList(Long clerkId, String facingSlip) {
		DetachedCriteria criteria = DetachedCriteria.forClass(TallyingEntity.class);
		criteria.add(Restrictions.eq("tallyingState", TallyingStateEnum.IN_TALLY));
		criteria.add(Restrictions.eq("clerkId", clerkId));
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("tallyingId")));
		List<Long> tallyingIds = PersistUtil.get(criteria);
		if (tallyingIds.isEmpty()) {
			return new ArrayList<ContainerInventoryEntity>();
		}
		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.in("tallyingId", tallyingIds));
		criteria.add(Restrictions.or(Restrictions.like("facingSlip", "%" + facingSlip + "%"), Restrictions.like("facingSlipNext", "%" + facingSlip + "%")));
		return PersistUtil.get(criteria);
	}

	@Override
	public PageList<ContainerInventoryEntity> inquireContainerInventoryPageList(String financeNumber, String beginDate, String endDate, String waybillNumber, String caseNumber, String enterpriseName, Long financeId, Integer inventoryState,
			PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (financeId != null && financeId != 0) {
			criteria.add(Restrictions.eq("financeId", financeId));
		}
		if (StringUtils.isNotBlank(beginDate)) {
			criteria.add(Restrictions.gt("tallyDateTime", DateUtils.formatBeginDay(beginDate)));
		}
		if (StringUtils.isNotBlank(endDate)) {
			criteria.add(Restrictions.gt("tallyDateTime", DateUtils.formatEndDay(endDate)));
		}
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		if (StringUtils.isNotBlank(enterpriseName)) {
			criteria.add(Restrictions.like("enterpriseName", "%" + enterpriseName + "%"));
		}
		if (StringUtils.isNotBlank(financeNumber)) {
			criteria.add(Restrictions.like("financeNumber", "%" + financeNumber + "%"));
		}
		if (inventoryState == null) {
			inventoryState = 0;
		}
		// 1:交割/2:到港/3:已提/4:可提/5:在押/6:异常
		if (inventoryState!=null && inventoryState.intValue() == 1) {
			criteria.add(Restrictions.in("supervisionState", new SupervisionStateEnum[] { SupervisionStateEnum.ALREADY_SUPERVISE, SupervisionStateEnum.RELIEVE_SUPERVISE }));
		}
		if (inventoryState!=null && inventoryState.intValue() == 2) {
			criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
		}
		if (inventoryState!=null && inventoryState.intValue() == 3) {
			criteria.add(Restrictions.eq("signState", Boolean.TRUE));
		}
		if (inventoryState!=null && inventoryState.intValue() == 4) {
			criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
			criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
			criteria.add(Restrictions.eq("signState", Boolean.FALSE));
			criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		}
		if (inventoryState!=null && inventoryState.intValue() == 5) {
			criteria.add(Restrictions.eq("abnormal", Boolean.FALSE));
		}
		criteria.addOrder(Order.asc("waybillNumber"));
		return PersistUtil.get(criteria, page);
	}

	@Override
	public List<ContainerInventoryEntity> inquireContainerInventory(String financeNumber, String waybillNumber, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (StringUtils.isNotBlank(financeNumber)) {
			criteria.add(Restrictions.like("financeNumber", "%" + financeNumber + "%"));
		}
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireSupervisionFinanceAmountList(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
//		criteria.add(Restrictions.eq("containerSource", BulkstockSourceEnum.FINANCE));
		criteria.add(Restrictions.in("supervisionState", new SupervisionStateEnum[] { SupervisionStateEnum.DELIVERY_SURE, SupervisionStateEnum.ALREADY_SUPERVISE, SupervisionStateEnum.RELIEVE_SUPERVISE }));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireExchangeContainerInventoryList(Long exchangePickupId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("exchangePickupId", exchangePickupId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireReplenishContainerInventoryList(Long replenishCreditId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("replenishCreditId", replenishCreditId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquirePickupExchangeContainerInventoryList(Long exchangePickupId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("exchangePickupId", exchangePickupId));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<Long> inquireFinanceIdFromContainerInventory(String waybillNumber, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("financeId")));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<Long> inquireFinanceIdFromContainerInventorys(String financeContractNumber,String financeContractSerialNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceContractEntity.class);
		if (StringUtil.isNotBlank(financeContractNumber)) {
			criteria.add(Restrictions.like("financeContractNumber", "%" + financeContractNumber + "%"));
		}
		if (StringUtil.isNotBlank(financeContractSerialNumber)) {
			criteria.add(Restrictions.like("financeContractSerialNumber", "%" + financeContractSerialNumber + "%"));
		}
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("financeContractId")));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<Long> inquirePickupIdFromContainerInventory(String waybillNumber, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.like("waybillNumber", "%" + waybillNumber + "%"));
		}
		if (StringUtils.isNotBlank(caseNumber)) {
			criteria.add(Restrictions.like("caseNumber", "%" + caseNumber + "%"));
		}
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("pickupId")));
		return PersistUtil.get(criteria);
	}

	@Override
	public List<ContainerInventoryEntity> inquireContainerInventoryList(
			String waybillNumber, Long enterpriseId, Integer type) {
		PageCriteria page = null;
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (StringUtils.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.eq("waybillNumber", waybillNumber));
		}
		if (enterpriseId != null) {
			criteria.add(Restrictions.eq("enterpriseId", enterpriseId));
		}
		if (type != null) {
			criteria.add(Restrictions.isNull("type"));
			page = new PageCriteria(0, 500);
		}
		criteria.addOrder(Order.desc("waybillNumber"));
		if (page != null) {
			return PersistUtil.get(criteria, page);
		} else {
			return PersistUtil.get(criteria);
		}
	}

	@Override
	public ContainerInventoryEntity inquireContainerInventory(String waybillNumber, String caseNumber) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		if (StringUtil.isNotBlank(waybillNumber)) {
			criteria.add(Restrictions.eq("waybillNumber", waybillNumber.trim()));
		}
		criteria.add(Restrictions.eq("caseNumber", caseNumber.trim()));
		List<ContainerInventoryEntity> list = PersistUtil.get(criteria);
		if (list != null && !list.isEmpty()) {
			return list.get(0);
		} else {
			return null;
		}
	}
}
